package com.ruoyi.qiuyue.controller;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.qiuyue.common.JWTUtils;
import com.ruoyi.qiuyue.common.UserConstat;
import com.ruoyi.qiuyue.domain.MusicUser;
import com.ruoyi.qiuyue.domain.vo.UserVo;
import com.ruoyi.qiuyue.handler.exception.RedisCodeException;
import com.ruoyi.qiuyue.service.IMusicUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.web.bind.annotation.*;

import java.time.Duration;
import java.util.HashMap;

/**
 * 安全相关类
 */
@RestController
@RequestMapping("/app/auth")
public class AuthController {
    @Autowired
    private IMusicUserService musicUserService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private JWTUtils jwtUtils;

    /**
     * 用户注册
     * @param user
     * @return
     */
    @PostMapping("/register")
    public AjaxResult register(@RequestBody UserVo user){
        // 检查验证码
        checkRedisCode(user);
        // 注册
        MusicUser musicUser = new MusicUser();
        musicUser.setAccount(user.getAccount());
        musicUser.setPassword(user.getPassword());
        musicUserService.insertMusicUser(musicUser);
        return AjaxResult.success(UserConstat.USER_REGISTER);
    }

    /**
     * 用户登录
     * @param user
     * @return
     */
    @PostMapping("/login")
    public AjaxResult login(@RequestBody UserVo user) {
        // 检查验证码
        checkRedisCode(user);
        // 验证账号
        MusicUser musicUser = musicUserService.getMusicUserByAccount(user.getAccount(), user.getPassword());
        // 响应token
        String jwtToken = jwtUtils.getJwtToken(musicUser.getId(), musicUser.getAccount());
        HashMap<String, String> data = new HashMap<>();
        data.put("token",jwtToken);
        return AjaxResult.success(UserConstat.USER_LOGIN).put("data",data);
    }

    /**
     * 修改密码
     * @param user
     * @return
     */
    @PostMapping("/forget")
    public AjaxResult forget(@RequestBody UserVo user) {
        // 检查验证码
        checkRedisCode(user);
        // 验证账号
        MusicUser musicUser = musicUserService.forgetUserByAccount(user.getAccount(), user.getPassword());
        String jwtToken = jwtUtils.getJwtToken(musicUser.getId(), musicUser.getAccount());
        // 响应token
        HashMap<String, String> data = new HashMap<>();
        data.put("token",jwtToken);
        return AjaxResult.success(UserConstat.USER_FORGET).put("data",data);
    }

    /**
     * 为账号分配验证码
     * @param account 账号
     * @return
     */
    @PostMapping("/captcha")
    public AjaxResult captcha(@RequestBody String account){
        // 生成验证码保存redis
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        String code = lineCaptcha.getCode();
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(UserConstat.USER_REDIS_CODE+account,code
                , Duration.ofMinutes(UserConstat.USER_REDIS_CODE_TIMEOUT_MINUTES));
        // 响应base64
        HashMap<String, String> data = new HashMap<>();
        String base64Data = lineCaptcha.getImageBase64();
        data.put("code",base64Data);
        return AjaxResult.success().put("data",data);
    }

    /**
     * 验证redis用户验证码
     * @param user
     */
    private void checkRedisCode(UserVo user) {
        ValueOperations valueOperations = redisTemplate.opsForValue();
        String codeKey = UserConstat.USER_REDIS_CODE + user.getAccount();
        String code = (String)(valueOperations.get(codeKey));
        boolean isNotExistsCode = StringUtils.isEmpty(code);
        if (isNotExistsCode || !user.getCode().equals(code)){
            throw new RedisCodeException();
        }
    }
}
